package com.rich.datapump.biz.datasource

import com.mybatisflex.core.FlexGlobalConfig
import com.mybatisflex.core.row.Db
import com.mybatisflex.core.row.Row
import com.zaxxer.hikari.HikariDataSource
import org.noear.snack.ONode
import org.noear.solon.annotation.Controller
import org.noear.solon.annotation.Inject
import org.noear.solon.annotation.Mapping
import java.io.File
import java.io.Serializable
import kotlin.reflect.javaType
import kotlin.reflect.typeOf


@Controller
@Mapping("datasource")
class DataSourceController {

    @Inject
    lateinit var dsHandler: CurrDSHandler

    @OptIn(ExperimentalStdlibApi::class)
    @Mapping("add")
    fun add(dbInfo: DBInfo): String {
        // 设置数据源
        val defaultConfig = FlexGlobalConfig.getDefaultConfig()
        val flexDataSource = defaultConfig.dataSource
        //新的数据源
        val newDataSource = HikariDataSource()
        newDataSource.jdbcUrl = dbInfo.url
        newDataSource.username = dbInfo.username
        newDataSource.password = dbInfo.password
        newDataSource.driverClassName = dbInfo.driverClassName()

        flexDataSource.addDataSource(dbInfo.name, newDataSource)
        // 应用数据源
        dsHandler.usingDBInfo = dbInfo
        // 读取历史记录
        val file = File("${System.getProperty("user.dir")}/DBInfo.json")
        var list = mutableListOf<DBInfo>()
        if (file.exists()) {
            val dbinfoJson = file.readText()
            if (dbinfoJson.startsWith("[") && dbinfoJson.endsWith("]"))
                list = ONode.deserialize(dbinfoJson, typeOf<MutableList<DBInfo>>().javaType)
        }
        // 存在则调整位置到尾部并更新信息
        list.find { it.name == dbInfo.name }?.let {
            list.remove(it)
        }
        list.add(dbInfo)
        // 写入文件
        overWriteDataSourceFile(ONode.stringify(list))

        return "${dbInfo}添加成功"
    }

    /**
     * 覆盖数据源存储文件
     */
    private fun overWriteDataSourceFile(data: String) =
        File("${System.getProperty("user.dir")}/DBInfo.json").writeText(data)

    @Mapping("dbinfoList")
    fun dbinfoList(): String {
        val file = File("${System.getProperty("user.dir")}/DBInfo.json")
        return if (file.exists())
            file.readText()
        else
            "[]"
    }

    private fun extracted() {
        val rows: List<Row> = Db.selectAll("S_CODETYPE")
        println(rows)
    }

    @Mapping("configDatabase")
    fun configDatabase(dbInfo: DBInfo): String {
        add(dbInfo)
        return dsHandler.getCurrDSMapper().getVersion()
    }

}